<template>
<div class="tab-pane active" id="gb-config" v-loading="bUploading">
  <form class="form-horizontal" autocomplete="off" spellcheck="false" @submit.prevent="onGBSubmit" data-vv-scope="gb">
    <div :class="['form-group' , {'has-error': errors.has('gb.serial')}]">
      <label for="gb-serial" class="col-sm-3 control-label">SIP 服务ID</label>
      <div class="col-sm-8">
        <input type="text" id="gb-serial" class="form-control" name="serial" data-vv-as="SIP 服务ID" v-validate="'alpha_dash'" v-model.trim="Serial" @keyup="serialChange" @blur="serialChange">
        <!-- <span class="help-block">{{errors.first('gb.serial')}}</span> -->
      </div>
    </div>
    <div :class="['form-group' , {'has-error': errors.has('gb.realm')}]">
      <label for="gb-realm" class="col-sm-3 control-label">SIP 服务域</label>
      <div class="col-sm-8">
        <input type="text" id="gb-realm" class="form-control" name="realm" data-vv-as="SIP 服务域" v-model.trim="Realm">
        <!-- <span class="help-block">{{errors.first('gb.realm')}}</span> -->
      </div>
    </div>
    <div :class="['form-group' , {'has-error': errors.has('gb.ip')}]">
      <label for="gb-ip" class="col-sm-3 control-label">SIP 服务IP</label>
      <div class="col-sm-8">
        <input type="text" id="gb-ip" class="form-control" name="ip" data-vv-as="SIP 服务IP" v-model.trim="IP">
        <!-- <span class="help-block">{{errors.first('gb.ip')}}</span> -->
      </div>
    </div>
    <div :class="['form-group' , {'has-error': errors.has('gb.port')}]">
      <label for="gb-port" class="col-sm-3 control-label">SIP 服务端口</label>
      <div class="col-sm-8">
        <div class="input-group" v-if="Enable && Status == 'OK'">
          <input type="text" id="gb-port" class="form-control" name="port" data-vv-as="SIP 服务端口" v-validate="'numeric'" v-model.trim="Port">
          <span class="input-group-btn">
            <button @click="push" type="button" class="btn btn-default" style="border-top-right-radius:0;border-bottom-right-radius:0;" title="主动将通道目录推送至上级国标服务">推送通道</button>
          </span>
        </div>
        <input v-else type="text" id="gb-port" class="form-control" name="port" data-vv-as="SIP 服务端口" v-validate="'numeric'" v-model.trim="Port">
        <!-- <span class="help-block">{{errors.first('gb.port')}}</span> -->
      </div>
    </div>
    <div :class="['form-group' , {'has-error': errors.has('gb.local_ip')}]">
      <label for="gb-local-ip" class="col-sm-3 control-label" title="默认自动获取">本地 IP</label>
      <div class="col-sm-8">
        <input type="text" id="gb-local-ip" class="form-control" name="local_ip" data-vv-as="本地 IP" v-model.trim="LocalIP" placeholder="可选 默认自动获取">
        <!-- <span class="help-block">{{errors.first('gb.local_ip')}}</span> -->
      </div>
    </div>
    <div :class="['form-group' , {'has-error': errors.has('gb.local_port')}]">
      <label for="gb-local-port" class="col-sm-3 control-label" title="配置为0, 表示自动分配">本地 SIP 端口</label>
      <div class="col-sm-8">
        <input type="text" id="gb-local-port" class="form-control" name="local_port" data-vv-as="本地 SIP 端口" v-validate="'numeric'" v-model.trim="LocalPort" placeholder="可选 默认自动分配">
        <!-- <span class="help-block">{{errors.first('gb.local_port')}}</span> -->
      </div>
    </div>
    <div :class="['form-group' , {'has-error': errors.has('gb.command_transport')}]">
      <label for="gb-command-transport" class="col-sm-3 control-label">信令传输模式</label>
      <div class="col-sm-8">
        <select id="gb-command-transport" class="form-control" name="command_transport" data-vv-as="信令传输模式" v-model.trim="CommandTransport">
          <option value="UDP">UDP</option>
          <option value="TCP">TCP</option>
        </select>
        <!-- <span class="help-block">{{errors.first('gb.command_transport')}}</span> -->
      </div>
    </div>
    <div :class="['form-group' , {'has-error': errors.has('gb.user')}]">
      <label for="gb-user" class="col-sm-3 control-label">设备国标编号</label>
      <div class="col-sm-8">
        <div class="input-group">
          <input type="text" id="gb-user" class="form-control" name="user" data-vv-as="设备国标编号" v-model.trim="User">
          <span class="input-group-btn">
            <button @click="genGBID" type="button" class="btn btn-default" style="border-top-right-radius:0;border-bottom-right-radius:0;" :title="genGBIDTitle">{{genGBIDText}}</button>
          </span>
        </div>
        <!-- <span class="help-block">{{errors.first('gb.user')}}</span> -->
      </div>
    </div>
    <div :class="['form-group' , {'has-error': errors.has('gb.password')}]">
      <label for="gb-password" class="col-sm-3 control-label">接入密码</label>
      <div class="col-sm-8">
        <div class="input-group">
          <input type="text" id="gb-password" class="form-control" name="password" data-vv-as="接入密码" v-model.trim="Password" v-if="rawPwd">
          <input type="password" id="gb-password" class="form-control" name="password" autocomplete="new-password" data-vv-as="接入密码" v-model.trim="Password" v-else
            onfocus="this.readOnly = false;" onblur="this.readOnly = true;" style="background-color: #FFF;" readonly>
          <span class="input-group-btn">
              <button type="button" class="btn btn-default" @click="rawPwd = !rawPwd;" style="border-top-right-radius:0;border-bottom-right-radius:0;">
                  <i class="glyphicon glyphicon-eye-open" v-if="rawPwd"></i>
                  <i class="glyphicon glyphicon-eye-close" v-else></i>
              </button>
          </span>
        </div>
        <!-- <span class="help-block">{{errors.first('gb.password')}}</span> -->
      </div>
    </div>
    <div :class="['form-group' , {'has-error': errors.has('gb.register_interval')}]">
      <label for="gb-register-interval" class="col-sm-3 control-label"> 注册周期(秒)</label>
      <div class="col-sm-8">
        <input type="text" id="gb-register-interval" class="form-control" name="register_interval" data-vv-as="注册周期" v-validate="'numeric'" v-model.trim="RegisterInterval">
        <!-- <span class="help-block">{{errors.first('gb.register_interval')}}</span> -->
      </div>
    </div>
    <div :class="['form-group' , {'has-error': errors.has('gb.keepalive_interval')}]">
      <label for="gb-keepalive-interval" class="col-sm-3 control-label"> 心跳周期(秒)</label>
      <div class="col-sm-8">
        <input type="text" id="gb-keepalive-interval" class="form-control" name="keepalive_interval" data-vv-as="心跳周期" v-validate="'numeric'" v-model.trim="KeepaliveInterval">
        <!-- <span class="help-block">{{errors.first('gb.keepalive_interval')}}</span> -->
      </div>
    </div>
    <div class="form-group">
        <label for="gb-gm-enable" class="col-sm-3 control-label">35114 国密认证</label>
        <div class="col-sm-8 checkbox">
            <el-checkbox id="gb-gm-enable" style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="GM" name="gm">
              启用国密&nbsp;&nbsp;
            </el-checkbox>
            <el-upload action="/api/v1/gm/ca/import" accept=".pem,.cer,.crt,.csr,.der" v-if="GM"
              style="display:inline-block;margin-right:7px;" :show-file-list="false"
              :on-success="onUploadCACertSuccess" :on-error="onUploadCACertError" :on-progress="onUploadCACertProgress">
              <a role="button" title="上传CA国密证书" v-if="!GMCACert">
                <i class="fa fa-upload"></i> 上传CA证书
              </a>
              <a role="button" title="重新上传CA国密证书" v-else>
                <i class="fa fa-upload"></i> 重新上传CA证书
              </a>
            </el-upload>
            <el-upload action="/api/v1/gm/cert/import?server=1" accept=".pem,.cer,.crt,.csr,.der" v-if="GM"
              style="display:inline-block;margin-right:7px;" :show-file-list="false"
              :on-success="onUploadServerCertSuccess" :on-error="onUploadServerCertError" :on-progress="onUploadServerCertProgress">
              <a role="button" title="上传远端服务国密证书" v-if="!GMServerCert">
                <i class="fa fa-upload"></i> 上传服务证书
              </a>
              <a role="button" title="重新上传远端服务国密证书" v-else>
                <i class="fa fa-upload"></i> 重新上传服务证书
              </a>
            </el-upload>
            <a role="button" title="创建证书请求" @click="$refs['gm-req-dlg'].show(User)" v-if="GM">
              <i class="fa fa-certificate" aria-hidden="true"></i> 创建证书请求
            </a>
        </div>
    </div>
    <div class="form-group" v-if="GM && GMCerts.length > 0">
      <label class="col-sm-3 control-label" @click="getGMCerts">国密证书</label>
      <div class="col-sm-8">
        <el-table :data="GMCerts" stripe v-loading="bCertLoading" element-loading-text="加载中...">
          <el-table-column min-width="100" label="证书功能" prop="Description" show-overflow-tooltip></el-table-column>
          <el-table-column min-width="200" label="签发给" prop="Subject" :formatter="formatCommonName" show-overflow-tooltip></el-table-column>
          <el-table-column min-width="200" label="签发者" prop="Issuer" show-overflow-tooltip>
            <template slot-scope="scope">
              <span v-if="scope.row.Type == 4">
                <a role="button" @click="$refs['gm-cert-dlg'].show(scope.row.Name)" title="创建自签名的本地国密证书">
                  <i class="fa fa-edit"></i> 自签名
                </a>
                &nbsp;&nbsp;
                <el-upload :action="`/api/v1/gm/cert/import?req=${scope.row.Name}`" accept=".pem,.cer,.crt,.csr,.der"
                  style="display:inline-block;margin-right:7px;" :show-file-list="false"
                  :on-success="onUploadLocalCertSuccess" :on-error="onUploadLocalCertError" :on-progress="onUploadLocalCertProgress">
                  <a role="button" title="上传CA签名的本地国密证书">
                    <i class="fa fa-upload"></i> CA签名
                  </a>
                </el-upload>
              </span>
              <span v-else>{{formatCommonName(scope.row, scope.column, scope.row.Issuer)}}</span>
            </template>
          </el-table-column>
          <el-table-column min-width="200" label="有效期" :formatter="formatCertDays" show-overflow-tooltip></el-table-column>
          <el-table-column min-width="280" label="序列号" prop="SN" show-overflow-tooltip></el-table-column>
          <el-table-column min-width="160" label="修改时间" prop="ModAt" show-overflow-tooltip></el-table-column>
          <el-table-column min-width="120" label="操作" :fixed="isMobile() ? false : 'right'">
            <template slot-scope="scope">
              <div class="btn-group">
                <a role="button" class="btn btn-info btn-xs" @click.prevent="downloadCert(scope.row.Name)"><i class='fa fa-download'></i> 下载</a>
                <a role="button" class="btn btn-danger btn-xs" @click.prevent="removeCert(scope.row.Name, scope.row.Description)"><i class='fa fa-remove'></i> 删除</a>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
    <div class="form-group">
      <label for="gb-enable" class="col-sm-3 control-label">其它配置</label>
      <div class="col-sm-8 checkbox">
        <el-checkbox id="gb-log" style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="Log" name="log">
          信令日志&nbsp;&nbsp;
        </el-checkbox>
        <el-checkbox id="gb-control" style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="AllowControl" name="control" title="是否允许上级平台操作云台">
          云台控制&nbsp;&nbsp;
        </el-checkbox>
        <el-checkbox id="gb-record" style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="ShareRecord" name="record" title="是否共享录像给上级">
          共享录像&nbsp;&nbsp;
        </el-checkbox>
        <el-checkbox id="gb-sync-time" style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="SyncTime" name="sync_time" title="以上级为时钟源进行校时, 需要以管理员权限运行">
          启用校时&nbsp;&nbsp;
        </el-checkbox>
        <el-checkbox id="gb-rtcp" style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="RTCPKeepalive" name="rtcp" title="开启RTCP流保活可防止产生野流">
          RTCP流保活
        </el-checkbox>
        <!-- <span class="help-block"></span> -->
      </div>
    </div>
    <div class="form-group">
      <div class="col-sm-offset-3 col-sm-8 checkbox">
        <el-checkbox id="gb-enable" style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="Enable" name="enable">
          启用级联
        </el-checkbox>
        &nbsp;&nbsp;&nbsp;&nbsp;
        <button type="submit" class="btn btn-primary" :disabled="isGBNoChange || errors.any('gb') || bCommitting || bUploading">保存</button>
      </div>
    </div>
    <div :class="['form-group' , {'has-error': Enable && !Online, 'has-success': Enable && Online}]">
      <div class="col-sm-offset-3 col-sm-8">
        <a role="button" class="text-success" @click.prevent="showSession" title="点击查看会话列表"
          v-if="Enable && Online && Load">{{Status}}&nbsp;&nbsp;{{Load}}</a>
        <span class="help-block" v-else>{{Status}}&nbsp;</span>
      </div>
    </div>
  </form>
  <GmReqDlg ref="gm-req-dlg" action="/api/v1/gm/req/create" @submit="getGMCerts"></GmReqDlg>
  <GmCertDlg ref="gm-cert-dlg" action="/api/v1/gm/cert/create" @submit="getGMCerts"></GmCertDlg>
  <GBSessionListDlg ref="gb-sess-dlg" size="modal-lgg"></GBSessionListDlg>
</div>
</template>

<script>
import GmReqDlg from 'components/GmReqDlg.vue';
import GmCertDlg from 'components/GmCertDlg.vue';
import GBSessionListDlg from 'components/GBSessionListDlg.vue';
import $ from "jquery";
import moment from 'moment';
export default {
  data() {
    return {
      bCommitting: false,
      bUploading: false,
      bCertLoading: false,
      Serial: "",
      Realm: "",
      IP: "",
      Port: 15060,
      LocalIP: "",
      LocalPort: "",
      User: "",
      Password: "",
      CommandTransport: "TCP",
      RegisterInterval: 300,
      KeepaliveInterval: 60,
      RTCPKeepalive: false,
      AllowControl: true,
      ShareRecord: true,
      MergeRecord: false,
      SyncTime: false,
      Status: "",
      Load: "",
      Online: false,
      Enable: false,
      rawPwd: true,
      Log: false,
      GM: false,
      GMCACert: "",
      GMServerCert: "",
      GMCerts: [],
      remoteGBData: "",
      timer: 0,
      genGBIDTitle: "一键自动生成所有通道国标编号, 否则需要在[通道配置]中逐条配置",
      genGBIDText: "清空通道编号",
    };
  },
  components: {
      GmReqDlg, GmCertDlg, GBSessionListDlg
  },
  mounted() {
    this.getGBConfig();
    this.getGMCerts();
    this.timer = setInterval(() => {
      this.getGBConfig(true);
    }, 2000);
  },
  beforeDestroy() {
    if (this.timer) {
      clearInterval(this.timer);
      this.timer = 0;
    }
  },
  watch: {
      User: function(val, oldVal) {
        if(!val) {
          this.genGBIDTitle = "一键清空所有通道国标编号";
          this.genGBIDText = "清空通道编号";
        } else {
          this.genGBIDTitle = "一键自动生成所有通道国标编号, 否则需要在[通道配置]中逐条配置";
          this.genGBIDText = "生成通道编号";
        }
      }
  },
  methods: {
    async onGBSubmit() {
      var ok = await this.$validator.validateAll('gb');
      if (!ok) {
        var e = this.errors.items[0];
        this.$message({
          type: "error",
          message: e.msg
        });
        $(`[name=${e.field}]`).focus();
        return;
      }
      this.bCommitting = true;
      $.get("/api/v1/setgbconfig", this.getGBCommitObject()).then(data => {
        if ((data.LiveQing || data.NVR).Header.ErrorNum == 200) {
          this.$message({
            type: "success",
            message: "配置成功！"
          });
          this.getGBConfig();
        } else {
          this.$message({
            type: "error",
            message: "配置失败！"
          });
        }
      }).always(() => {
        this.bCommitting = false;
      })
    },
    serialChange() {
      if(!this.Serial) return;
      if(this.Serial.length >= 10 && !this.Realm) {
        this.Realm = this.Serial.substring(0, 10);
      }
    },
    genGBID() {
      this.$confirm(`此操作将${this.User ? '重新生成' : '清空'}所有国标通道编号, 是否继续?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
      }).then(() => {
          this.bCommitting = true;
          $.get("/api/v1/gengbid", {
            realm: this.User,
          }).then(data => {
            this.$message({
              type: "success",
              message: "配置成功！"
            })
          }).always(() => {
            this.bCommitting = false;
          })
      }).catch(() => {});
    },
    push() {
      this.bCommitting = true;
      $.get("/api/v1/gbpush").then(() => {
        this.$message({
          type: "success",
          message: "推送成功！"
        })
      }).always(() => {
        this.bCommitting = false;
      })
    },
    getGBCommitObject() {
      return {
        Serial: this.Serial,
        Realm: this.Realm,
        IP: this.IP,
        Port: this.Port,
        LocalIP: this.LocalIP,
        LocalPort: this.LocalPort,
        User: this.User,
        Password: this.Password,
        CommandTransport: this.CommandTransport,
        RegisterInterval: this.RegisterInterval,
        KeepaliveInterval: this.KeepaliveInterval,
        RTCPKeepalive: this.RTCPKeepalive,
        AllowControl: this.AllowControl,
        ShareRecord: this.ShareRecord,
        MergeRecord: this.MergeRecord,
        SyncTime: this.SyncTime,
        Enable: this.Enable,
        Log: this.Log,
        GM: this.GM,
      };
    },
    getGBConfig(statusOnly) {
      $.get("/api/v1/getgbconfig").then(data => {
        var body = (data.LiveQing || data.NVR).Body;
        if (!body) return;
        this.Online = !!body.Online;
        this.Status = body.Status || "";
        this.Load = body.SessCnt > 0 ? `Load[${body.SessCnt}]` : "";
        if (statusOnly) {
          return
        }
        this.Serial = body.Serial || "";
        this.Realm = body.Realm || "";
        this.IP = body.IP || "";
        this.Port = body.Port || 15060;
        this.LocalIP = body.LocalIP || "";
        this.LocalPort = body.LocalPort || "";
        this.User = body.User || "";
        this.CommandTransport = body.CommandTransport || "TCP";
        this.RegisterInterval = body.RegisterInterval || 300;
        this.KeepaliveInterval = body.KeepaliveInterval || 60;
        this.RTCPKeepalive = !!body.RTCPKeepalive;
        this.AllowControl = !!body.AllowControl;
        this.ShareRecord = !!body.ShareRecord;
        this.MergeRecord = !!body.MergeRecord;
        this.SyncTime = !!body.SyncTime;
        this.Enable = !!body.Enable;
        this.Log = !!body.Log;
        this.GM = !!body.GM;
        this.GMCACert = body.GMCACert || "";
        this.GMServerCert = body.GMServerCert || "";
        setTimeout(() => {
          this.Password = body.Password || "";
          this.rawPwd = false;
          this.remoteGBData = JSON.stringify(this.getGBCommitObject());
        }, 300);
      });
    },
    onUploadCACertSuccess(res, file, fileList) {
        this.bUploading = false;
        this.GMCACert = res;
        this.getGMCerts();
        this.$message({
          type: "success",
          message: "上传CA证书成功！"
        });
    },
    onUploadCACertProgress(evt, file, fileList) {
        this.bUploading = true;
    },
    onUploadCACertError(err, file, fileList) {
        this.bUploading = false;
        if (err) {
            this.$message({
                type: "error",
                message: err + ""
            })
        }
    },
    onUploadServerCertSuccess(res, file, fileList) {
        this.bUploading = false;
        this.GMServerCert = res;
        this.getGMCerts();
        this.$message({
          type: "success",
          message: "上传服务证书成功！"
        });
    },
    onUploadServerCertProgress(evt, file, fileList) {
        this.bUploading = true;
    },
    onUploadServerCertError(err, file, fileList) {
        this.bUploading = false;
        if (err) {
            this.$message({
                type: "error",
                message: err + ""
            })
        }
    },
    onUploadLocalCertSuccess(res, file, fileList) {
        this.bUploading = false;
        this.getGMCerts();
        this.$message({
          type: "success",
          message: "上传本地证书成功！"
        });
    },
    onUploadLocalCertProgress(evt, file, fileList) {
        this.bUploading = true;
    },
    onUploadLocalCertError(err, file, fileList) {
        this.bUploading = false;
        if (err) {
            this.$message({
                type: "error",
                message: err + ""
            })
        }
    },
    downloadCert(fname) {
      var link = "/api/v1/gm/cert/download";
      if(fname) {
        link += `?fname=${fname}`;
      }
      window.open(link, "_blank");
    },
    removeCert(fname, fdesc) {
      var msg = "确认删除证书?";
      if(fdesc) {
        msg = `确认删除${fdesc}?`;
      }
      this.$confirm(msg, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        var link = "/api/v1/gm/cert/remove";
        if(fname) {
          link += `?fname=${fname}`;
        }
        $.get(link).then(() => {
          if(fname == this.GMCACert) {
            this.GMCACert = "";
          }
          if(fname == this.GMServerCert) {
            this.GMServerCert = "";
          }
          this.getGMCerts();
        });
      }).catch(() => {});
    },
    getGMCerts() {
      this.bCertLoading = true;
      $.get("/api/v1/gm/cert/list").then(data => {
        this.GMCerts = data.CertList || [];
      }).always(() => {
        this.bCertLoading = false;
      })
    },
    formatCertDays(row, col, cell) {
      var t1 = moment(row["StartAt"], "YYYY-MM-DD HH:mm:ss");
      var t2 = moment(row["EndAt"], "YYYY-MM-DD HH:mm:ss");
      if(t1 && t2 && t1.year() > 1 && t2.year() > 1) {
        return `${t1.format("YYYY-MM-DD")} ~ ${t2.format("YYYY-MM-DD")}`;
      }
      return "-";
    },
    formatCommonName(row, col, cell) {
      var ret = cell || "-";
      var list = ret.split("_");
      if(list.length == 2) {
        ret = list[0] || "-";
      }
      return ret;
    },
    showSession() {
      this.$refs["gb-sess-dlg"].show(this.Serial, "级联一");
    },
  }, // methods
  computed: {
    isGBNoChange() {
      var localeData = JSON.stringify(this.getGBCommitObject());
      return this.remoteGBData.localeCompare(localeData) == 0;
    }
  }
};
</script>
